import { EventDispatcher } from "../../base/event/EventDispatcher";


enum EventType {
    ADD = "DictionaryEventType.ADD",
    REMOVE = "DictionaryEventType.REMOVE",
    UPDATE = "DictionaryEventType.UPDATE"
}

/**
 * 字典
 */
export class Dictionary<K, V> extends EventDispatcher {

    static EventType = EventType;

    private _map: Map<K, V> = new Map<K, V>();

    public get count():number{
        return this._map.size;
    };

    constructor() {
        super();
    }

    set(key: K, value: V): void {
        let old: V = this._map.get(key) as V;
        if (old) {
            //删除老的
            this.delete(key);
        }
        if (value) {
            //添加新的
            this._map.set(key, value);
            this._cacheElements.length = 0;
        }

        if (old && value) {
            //派发更新事件
            if (this.hasListener(Dictionary.EventType.UPDATE)) {
                this.event(Dictionary.EventType.UPDATE, { oldValue: old, newValue: value });
            }
        } else {
            if (old) {
                //派发删除事件
                if (this.hasListener(Dictionary.EventType.REMOVE)) {
                    this.event(Dictionary.EventType.REMOVE, old);
                }
            } else if (value) {
                //派发添加事件
                if (this.hasListener(Dictionary.EventType.ADD)) {
                    this.event(Dictionary.EventType.ADD, value);
                }
            }
        }
    }

    /**
     * 是否拥有指定KEY的元素
     * @param key 
     * @returns 
     */
    has(key: K): boolean {
        return this._map.has(key);
    }

    /**
     * 获取指定元素
     * @param key 
     * @returns 
     */
    get(key: K): V {
        return this._map.get(key) as V;
    }

    /**
     * 删除指定元素
     * @param key 
     * @returns 
     */
    delete(key: K): V | null {
        if (!this._map.has(key)) {
            return null;
        }
        const result = this._map.get(key) as V;
        this._map.delete(key);
        this._cacheElements.length = 0;
        //派发删除事件
        if (this.hasListener(Dictionary.EventType.REMOVE)) {
            this.event(Dictionary.EventType.REMOVE, result);
        }
        return result;
    }
    /**
     * 清除所有元素
     */
    clear(){
        this._cacheElements=[];
        this._map.clear();
    }
    private _cacheElements:Array<V>;
    /**
    * 元素列表
    */
    get elements(): Array<V> {
        if(this._cacheElements==null){
            this._cacheElements=[];
            this._map.forEach(function(v: V, key: K){
                this._cacheElements.push(v);
            }.bind(this));   
        }
        return this._cacheElements;
    }

    /**
     * key列表
     */
    get keys(): Array<K> {
        let _keys: Array<K> = [];
        this._map.forEach(function(v: V, key: K){
            _keys.push(key);
        })  
        return _keys;
    }
}
